package com.yanghui.dtracing.core.plugin.interceptor;

import com.yanghui.dtracing.core.log.ILog;
import com.yanghui.dtracing.core.log.LogManager;
import com.yanghui.dtracing.core.opentracing.DTracer;
import com.yanghui.dtracing.core.opentracing.Tracing;
import io.opentracing.Span;
import io.opentracing.tag.Tags;

import java.lang.reflect.Method;

public abstract class AbstractStaticMethodInterceptor extends AbstractMethodInterceptor implements IStaticMethodAroundInterceptor {

    private static final ILog log = LogManager.getLogger(AbstractStaticMethodInterceptor.class);

    @Override
    public final void beforeMethod(Class<?> clz, Method method, Object[] allArguments, MethodInterceptResult methodInterceptResult) throws Throwable {
        DTracer tracer = Tracing.getTracer();
        DTracer.SpanBuilder spanBuilder = (DTracer.SpanBuilder)tracer.buildSpan(method.getName()).withClassName(clz.getClass().getName())
                .withTag(Tags.SPAN_KIND.getKey(),Tags.SPAN_KIND_SERVER);
        try{
            this.doBuild(spanBuilder,clz,method,allArguments,methodInterceptResult);
        }catch (Throwable t){
            log.error("AbstractStaticMethodInterceptor.doBuild(instance) exception.",t);
        }
        Span span = spanBuilder.start();
        try{
            this.doBeforeMethod(clz,method,allArguments,methodInterceptResult,span);
        }catch (Throwable t){
            log.error("AbstractStaticMethodInterceptor.doBeforeMethod(static) exception.",t);
        }
        tracer.activateSpan(span);
    }

    protected void doBuild(DTracer.SpanBuilder spanBuilder, Class<?> clz, Method method, Object[] allArguments, MethodInterceptResult methodInterceptResult){

    }

    protected void doBeforeMethod(Class<?> clz, Method method, Object[] allArguments, MethodInterceptResult result,Span span) throws Throwable{
    }

    @Override
    public final void afterMethod(Class<?> clz, Method method, Object[] allArguments, MethodInterceptResult methodInterceptResult) throws Throwable {
        Span span = Tracing.getTracer().activeSpan();
        try{
            this.doAfterMethod(clz,method,allArguments,methodInterceptResult,span);
        }catch (Throwable t){
            log.error("AbstractStaticMethodInterceptor.doAfterMethod(static) exception.",t);
        }
        super.parseResult(span,methodInterceptResult);
        span.finish();
    }

    protected void doAfterMethod(Class<?> clz, Method method, Object[] allArguments, MethodInterceptResult result,Span span) throws Throwable{
    }

    @Override
    public final void handleMethodException(Class<?> clz, Method method, Object[] allArguments, Throwable t, MethodInterceptResult methodInterceptResult) throws Throwable {
        this.doMethodException(clz,method,allArguments,methodInterceptResult,this.exception(t));
    }
    protected void doMethodException(Class<?> clz, Method method, Object[] allArguments, MethodInterceptResult result,Span span) throws Throwable{
    }
}
